﻿
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using Dapper;
using OddUserManager.Model;
using OddUserManager.Data.IRepositories;

namespace OddUserManager.Data.Repositories
{
    //public class AppUserRepository : BaseRepository<AppUser, int>, IAppUserRepository
    //{
    //    public AppUserRepository(OddUserManagerDbContext dbContext) : base(dbContext)
    //    {
    //    }

    //    public AppUser CheckUser(string userName, string password)
    //    {
    //        return _dbContext.Set<AppUser>().FirstOrDefault(it => it.UserName == userName && it.Password == password);
    //    }

    //    public AppUser GetWithRoles(int id)
    //    {
    //        var user = _dbContext.Set<AppUser>().FirstOrDefault(it => it.Id == id);
    //        if (user != null)
    //        {
    //            user.UserRoles = _dbContext.Set<UserRoles>().Where(it => it.UserId == id).ToList();
    //        }
    //        return user;
    //    }
    //}


    public class AppUserRepository : DapperBaseRepository<AppUser, int>, IAppUserRepository
    {
        public AppUserRepository()
        {
        }



        public bool InsertOrUpdateUser(AppUser user)
        {
            bool isSuccess = false;
            var t = Get(user.Id);
            using (var con = GetOpenConnection())
            {
                var trans = con.BeginTransaction();
                try
                {
                    var propertyContainer = ParseProperties(user);
                    if (null == t)
                    {
                        //var sql = $"insert into {typeof(AppUser).Name} ({string.Join(", ", propertyContainer.ValueNames)}) values (@{string.Join(", @", propertyContainer.ValueNames)});SELECT SCOPE_IDENTITY():";
                        //var id = con.ExecuteScalar<int>(sql, propertyContainer.ValuePairs, trans, 3000, null);


                        var sql = $"INSERT INTO [dbo].[AppUser]([UserName],[UPassword],[Name],[Email] ,[MobileNumber] ,[Remarks],[CreateUserId],[CreateTime] ,[LastLoginTime],[LoginTimes],[IsDeleted])VALUES('{user.UserName}','{user.UPassword}','{user.Name}','{user.Email}','{user.MobileNumber}','{user.Remarks}',{user.CreateUserId},'{user.CreateTime}','{user.LastLoginTime}',{user.LoginTimes},{user.IsDeleted});SELECT SCOPE_IDENTITY()";
                        var id = con.ExecuteScalar<int>(sql, null, trans, 3000, null);
                        if (null != user.UserRoles && user.UserRoles.Count>0)
                        {
                            StringBuilder sb = new StringBuilder();
                            user.UserRoles.ToList().ForEach(p =>
                            {
                                sb.Append($"insert into UserRoles (UserId,RoleId) values({p.UserId},{p.RoleId})");
                            });
                            con.Execute(sb.ToString(), "", trans, 3000, null);
                        }
                    }
                    else
                    {
                        var updateSql = @"update AppUser set UserName=@UserName ,UPassword =@UPassword,Name=@Name,Email=@Email,MobileNumber=@MobileNumber,Remarks=@Remarks,CreateUserId=@CreateUserId,
                            IsDeleted= @IsDeleted where Id=@Id";
                        con.Execute(updateSql, user, trans, 3000, null);
                        var deleteSql = $"delete from UserRoles where UserId={user.Id}";
                        con.Execute(deleteSql, "", trans, 3000, null);
                        if (null != user.UserRoles && user.UserRoles.Count>0)
                        {
                            StringBuilder sb = new StringBuilder();
                            user.UserRoles.ToList().ForEach(p =>
                            {
                                sb.Append($"insert into UserRoles (UserId,RoleId) values({p.UserId},{p.RoleId});");
                            });
                            con.Execute(sb.ToString(), "", trans, 3000, null);
                        }
                    }
                    trans.Commit();
                    isSuccess = true;
                } catch (Exception ex)
                {
                    trans.Rollback();
                    throw ex;
                }
            }
            return isSuccess;
        }

        public bool UpdateLogonTime(int id, DateTime lastLogonTime, int logonTimes)
        {
            bool isSuccess = false;
            using (var con = GetOpenConnection())
            {
                var updateSql = @"update AppUser set LastLoginTime= @LastLoginTime,LoginTimes=@LoginTimes where Id=@Id";
                con.Execute(updateSql, new{Id=id, LastLoginTime= lastLogonTime, LoginTimes= logonTimes }, null, 3000, null);
            }
            return isSuccess;
        }
        //public AppUser Get(int id)
        //{
        //    AppUser t = null;
        //    using (var con = GetOpenConnection())
        //    {
        //        var sql = $"select * from {typeof(AppUser).Name} where Id={id.ToString()}";
        //        t = con.Query<AppUser>(sql).FirstOrDefault();
        //    }
        //    return t;
        //}

        public AppUser CheckUser(string userName, string password)
        {
            AppUser user = null;
            using (var con = GetOpenConnection())
            {
                var sql = $"select * from AppUser where UserName ='{userName}' and UPassword='{password}'";
                user = con.Query<AppUser>(sql).FirstOrDefault();
            }
                return user;
        }


        public AppUser GetWithRoles(int id)
        {
            AppUser user = null;
            user = Get(id);
            if (null != user)
            {
                using (var con = GetOpenConnection())
                {
                    var sql = $"select * from UserRoles where UserId={id}";
                    user.UserRoles = con.Query<UserRoles>(sql).ToList();
                }
            }
            return user;
        }

        public bool InsertOrUpdate(AppUser entity)
        {
            var t = Get(entity.Id);
            if (null == t)
            {
                return Insert(entity);
            }
            else
            {
                return Update(entity);
            }
        }

        //public IEnumerable<AppUser> GetAllList()
        //{
        //    List<AppUser> list = null;
        //    using (var con = GetOpenConnection())
        //    {
        //        var sql = $"select * from {typeof(AppUser).Name}";
        //        list = con.Query<AppUser>(sql, null, null, true, 3000, null).ToList();
        //    }
        //    return list;
        //}

        public IEnumerable<AppUser> LoadPageList(int startPage, int pageSize, out int rowCount, Func<AppUser, bool> where, Func<AppUser, object> order)
        {
            var result = GetAllList();
            if (where != null)
                result = result.Where(where);
            if (order != null)
                result = result.OrderBy(order);
            else
                result = result.OrderBy(m => m.Id);
            rowCount = result.Count();
            return result.Skip((startPage - 1) * pageSize).Take(pageSize);
        }

        
    }

}
